(function (window, T, util, object, string, dom) {
    var fx = T.fx = {};

    /**
     * 提供一个按时间进程的时间线类
     *
     * 本类提供两个方法：
     *  cancel()    取消操作
     *  end()       直接结束
     *
     * 使用本类时需要实现五个接口：
     *  initialize()            用于类初始化时的操作
     *  transition(percent)    重新计算时间线进度曲线
     *  finish()                用于类结束时时的操作
     *  render(schedule)        每个脉冲在DOM上的效果展现
     *  restore()               效果被取消时作的恢复操作
     *
     * @config {Number} interval 脉冲间隔时间（毫秒）
     * @config {Number} duration 时间线总时长（毫秒）
     * @config {Number} percent  时间线进度的百分比
     */
     
     
     
    /**
     * 提供一个按时间进程的时间线类
     * @class
     * @grammar new fx.Timeline(options)
     * @param {Object} options 参数
     * @config {Number} interval 脉冲间隔时间（毫秒）
     * @config {Number} duration 时间线总时长（毫秒）
     * @config {Number} percent  时间线进度的百分比
     */
    fx.Timeline = function(options){
        util.Class.call(this);

        this.interval = 16;
        this.duration = 500;
        this.dynamic  = true;

        object.extend(this, options);
    };
    util.inherits(fx.Timeline, util.Class, "fx.Timeline").extend({
    /**
     *  @lends fx.Timeline.prototype
     */
        /**
         * 启动时间线
         * @return {instance} 类实例
         */
        launch : function(){
            var me = this;
            me.dispatchEvent("onbeforestart");

            /**
            * initialize()接口，当时间线初始化同步进行的操作
            */
            typeof me.initialize =="function" && me.initialize();

            me["\x06btime"] = new Date().getTime();
            me["\x06etime"] = me["\x06btime"] + (me.dynamic ? me.duration : 0);
            me["\x06pulsed"]();

            return me;
        }

        /**
         * 每个时间脉冲所执行的程序
         * @ignore
         * @private
         */
        ,"\x06pulsed" : function(){
            var me = this;
            var now = new Date().getTime();
            // 当前时间线的进度百分比
            me.percent = (now - me["\x06btime"]) / me.duration;
            me.dispatchEvent("onbeforeupdate");

            // 时间线已经走到终点
            if (now >= me["\x06etime"]){
                typeof me.render == "function" && me.render(me.transition(me.percent = 1));

                // [interface run] finish()接口，时间线结束时对应的操作
                typeof me.finish == "function" && me.finish();

                me.dispatchEvent("onafterfinish");
                me.dispose();
                return;
            }

            /**
            * [interface run] render() 用来实现每个脉冲所要实现的效果
            * @param {Number} schedule 时间线的进度
            */
            typeof me.render == "function" && me.render(me.transition(me.percent));
            me.dispatchEvent("onafterupdate");

            me["\x06timer"] = setTimeout(function(){me["\x06pulsed"]()}, me.interval);
        }
        /**
         * 重新计算 schedule，以产生各种适合需求的进度曲线
         * @function
         * @param {Function} percent 
         */
        ,transition: function(percent) {
            return percent;
        }

        /**
         * 撤销当前时间线的操作，并引发 restore() 接口函数的操作
         * @function
         */
        ,cancel : function() {
            this["\x06timer"] && clearTimeout(this["\x06timer"]);
            this["\x06etime"] = this["\x06btime"];

            // [interface run] restore() 当时间线被撤销时的恢复操作
            typeof this.restore == "function" && this.restore();
            this.dispatchEvent("oncancel");

            this.dispose();
        }

        /**
         * 直接将时间线运行到结束点
         */
        ,end : function() {
            this["\x06timer"] && clearTimeout(this["\x06timer"]);
            this["\x06etime"] = this["\x06btime"];
            this["\x06pulsed"]();
        }
    });


    /**
     * 效果基类。
     * @function
     * @grammar fx.collapse(element, options, fxName)
     * @param     {HTMLElement}           element            添加效果的DOM元素
     * @param     {JSON}                  options            时间线的配置参数对象
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     * @param     {String}                fxName             效果名（可选）
     * @return {fx.Timeline}  时间线类的一个实例
     */
    fx.create = function(element, options, fxName) {
        var timeline = new fx.Timeline(options);

        timeline.element = element;
        timeline.__type = fxName || timeline.__type;
        timeline["\x06original"] = {};   // 20100708
        var catt = "baidu_current_effect";

        /**
         * 将实例的guid记录到DOM元素上，以便多个效果叠加时的处理
         */
        timeline.addEventListener("onbeforestart", function(){
            var me = this, guid;
            me.attribName = "att_"+ me.__type.replace(/\W/g, "_");
            guid = me.element.getAttribute(catt);
            me.element.setAttribute(catt, (guid||"") +"|"+ me.guid +"|", 0);

            if (!me.overlapping) {
                (guid = me.element.getAttribute(me.attribName)) 
                    && window[guid]._instances[guid].cancel();

                //在DOM元素上记录当前效果的guid
                me.element.setAttribute(me.attribName, me.guid, 0);
            }
        });

        /**
         * 打扫dom元素上的痕迹，删除元素自定义属性
         */
        timeline["\x06clean"] = function(e) {
            var me = this, guid;
            if (e = me.element) {
                e.removeAttribute(me.attribName);
                guid = e.getAttribute(catt);
                guid = guid.replace("|"+ me.guid +"|", "");
                if (!guid) e.removeAttribute(catt);
                else e.setAttribute(catt, guid, 0);
            }
        };

        /**
         * 在时间线结束时净化对DOM元素的污染
         */
        timeline.addEventListener("oncancel", function() {
            this["\x06clean"]();
            this["\x06restore"]();
        });

        /**
         * 在时间线结束时净化对DOM元素的污染
         */
        timeline.addEventListener("onafterfinish", function() {
            this["\x06clean"]();
            this.restoreAfterFinish && this["\x06restore"]();
        });

        /**
         * 保存原始的CSS属性值 20100708
         */
        timeline.protect = function(key) {
            this["\x06original"][key] = this.element.style[key];
        };

        /**
         * 时间线结束，恢复那些被改过的CSS属性值
         */
        timeline["\x06restore"] = function() {
            var o = this["\x06original"],
                s = this.element.style,
                v;
            for (var i in o) {
                v = o[i];
                if (typeof v == "undefined") continue;

                s[i] = v;    // 还原初始值

                // [TODO] 假如以下语句将来达不到要求时可以使用 cssText 操作
                if (!v && s.removeAttribute) s.removeAttribute(i);    // IE
                else if (!v && s.removeProperty) s.removeProperty(i); // !IE
            }
        };

        return timeline;
    };


    /**
     * fx 的所有 【属性、方法、接口、事件】 列表
     *
     * property【七个属性】                 默认值 
     *  element             {HTMLElement}           效果作用的DOM元素
     *  interval            {Number}        16      脉冲间隔时间（毫秒）
     *  duration            {Number}        500     时间线总时长（毫秒）
     *  percent             {Number}                时间线进度的百分比
     *  dynamic             {Boolean}       true    是否渐进式动画还是直接显示结果
     *  overlapping         {Boolean}       false   效果是否允许互相叠加
     *  restoreAfterFinish  {Boolean}       false   效果结束后是否打扫战场
     *
     * method【三个方法】
     *  end()       直接结束
     *  cancel()    取消操作
     *  protect()   保存元素原始的CSS属性值，以便自动 restore 操作
     *
     * event【四个事件】
     *  onbeforestart()
     *  onbeforeupdate()
     *  onafterupdate()
     *  onafterfinish()
     *
     * interface【五个接口】
     *  initialize()            用于类初始化时的操作
     *  transition(percent)     重新计算时间线进度曲线
     *  finish()                用于类结束时时的操作
     *  restore()               效果结束后的恢复操作
     *  render(schedule)        每个脉冲在DOM上的效果展现
     */


    /**
     * 从下向上收拢DOM元素的效果。
     * @function
     * @grammar fx.collapse(element, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms
     * @config    {String}                orientation        动画收拢方向，取值：vertical（默认），horizontal
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//在onafterfinish与oncancel时默认调用
     * @see fx.expand
     */

    fx.collapse = function(element, options) {
        if (!(element = dom.g(element))) return null;

        var e = element, 
            value, 
            attr,
            attrHV = {
                "vertical": {
                    value: 'height',
                    offset: 'offsetHeight',
                    stylesValue: ["paddingBottom","paddingTop","borderTopWidth","borderBottomWidth"]
                },
                "horizontal": {
                    value: 'width',
                    offset: 'offsetWidth',
                    stylesValue: ["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"]
                }
            };

        var fx = fx.create(e, object.extend({
            orientation: 'vertical'
            
            //[Implement Interface] initialize
            ,initialize : function() {
                attr = attrHV[this.orientation];
                this.protect(attr.value);
                this.protect("overflow");
                this.restoreAfterFinish = true;
                value = e[attr.offset];
                e.style.overflow = "hidden";
            }

            //[Implement Interface] transition
            ,transition : function(percent) {return Math.pow(1 - percent, 2);}

            //[Implement Interface] render
            ,render : function(schedule) {
                e.style[attr.value] = Math.floor(schedule * value) +"px";
            }

            //[Implement Interface] finish
            ,finish : function(){dom.hide(e);}
        }, options || {}), "fx.expand_collapse");

        return fx.launch();
    };

    // [TODO] 20100509 在元素绝对定位时，收缩到最后时会有一次闪烁

    /**
     * 获取DOM元素正在运行的效果实例列表
     * @function
     * @grammar fx.current(element)
     * @param     {string|HTMLElement}     element     被查询的DOM元素或元素id
     * @see fx.current
     * @returns {Array} 效果对象
     */
    fx.current = function(element) {
        if (!(element = dom.g(element))) return null;
        var a, guids, reg = /\|([^\|]+)\|/g;

        // 可以向<html>追溯
        do {if (guids = element.getAttribute("baidu_current_effect")) break;}
        while ((element = element.parentNode) && element.nodeType == 1);

        if (!guids) return null;

        if ((a = guids.match(reg))) {
            //fix
            //在firefox中使用g模式，会出现ture与false交替出现的问题
            reg = /\|([^\|]+)\|/;
            
            for (var i=0; i<a.length; i++) {
                reg.test(a[i]);
                a[i] = window[guid]._instances[RegExp["\x241"]];
            }
        }
        return a;
    };

    /**
     * 显示目标元素，即将目标元素的display属性还原成默认值。默认值可能在stylesheet中定义，或者是继承了浏览器的默认样式值
     * @author allstar, berg
     * @name dom.show
     * @function
     * @grammar dom.show(element)
     * @param {HTMLElement|string} element 目标元素或目标元素的id
     * @remark
     * 注意1：如果在CSS中定义此元素的样式为display:none
     * 在调用本函数以后，会将display属性仍然还原成none，元素仍然无法显示。
     * 注意2：如果这个元素的display属性被设置成inline
     * （由element.style.display或者HTML中的style属性设置）
     * 调用本方法将清除此inline属性，导致元素的display属性变成继承值
     * 因此，针对上面两种情况，建议使用dom.setStyle("display", "something")
     * 来明确指定要设置的display属性值。
     * 
     * @shortcut show
     * @meta standard
     * @see dom.hide,dom.toggle
     *             
     * @returns {HTMLElement} 目标元素
     */
    dom.show = function (element) {
        element = dom.g(element);
        element.style.display = "";

        return element;
    };

    // 声明快捷方法
    show = dom.show;


     
    /**
     * 自上而下展开DOM元素的效果。
     * @function
     * @grammar fx.expand(element, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms
     * @config    {String}                orientation        动画展开方向，取值：vertical（默认），horizontal
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     * @see fx.collapse
     */

    fx.expand = function(element, options) {
        if (!(element = dom.g(element))) return null;

        var e = element, 
            value, 
            attr,
            attrHV = {
                "vertical": {
                    value: 'height',
                    offset: 'offsetHeight',
                    stylesValue: ["paddingBottom","paddingTop","borderTopWidth","borderBottomWidth"]
                },
                "horizontal": {
                    value: 'width',
                    offset: 'offsetWidth',
                    stylesValue: ["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"]
                }
            };

        var fx = fx.create(e, object.extend({
            orientation: 'vertical'
            
            //[Implement Interface] initialize
            ,initialize : function() {
                attr = attrHV[this.orientation];
                dom.show(e);
                this.protect(attr.value);
                this.protect("overflow");
                this.restoreAfterFinish = true;
                value = e[attr.offset];
                
                function getStyleNum(d,style){
                    var result = parseInt(getStyle(d,style));
                    result = isNaN(result) ? 0 : result;
                    result = util.isNumber(result) ? result : 0;
                    return result;
                }
                
                each(attr.stylesValue, function(item){
                    value -= getStyleNum(e,item);
                });
                e.style.overflow = "hidden";
                e.style[attr.value] = "1px";
            }

            //[Implement Interface] transition
            ,transition : function(percent) {return Math.sqrt(percent);}

            //[Implement Interface] render
            ,render : function(schedule) {
                e.style[attr.value] = Math.floor(schedule * value) +"px";
            }
        }, options || {}), "fx.expand_collapse");

        return fx.launch();
    };
    /*
     * JavaScript framework: mz
     * Copyright (c) 2010 meizz, http://www.meizz.com/
     *
     * http://www.meizz.com/mz/license/ MIT-style license
     * The above copyright notice and this permission notice shall be
     * included in all copies or substantial portions of the Software
     */








     
    /**
     * 控制元素的透明度 渐变
     * @function
     * @grammar fx.opacity(element, options)
     * @param       {String|Object}           element               元素或者元素的ID
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  from                  0,//效果起始值。介于0到1之间的一个数字，默认为0。
     * @config      {Number}                  to                    1,//效果结束值。介于0到1之间的一个数字，默认为1。
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     */

    fx.opacity = function(element, options) {
        if (!(element = dom.g(element))) return null;

        options = object.extend({from: 0,to: 1}, options||{});

        var e = element;

        var fx = fx.create(e, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                dom.show(element);

                if (browser.ie) {
                    this.protect("filter");
                } else {
                    this.protect("opacity");
                    this.protect("KHTMLOpacity");
                }

                this.distance = this.to - this.from;
            }

            //[Implement Interface] render
            ,render : function(schedule) {
                var n = this.distance * schedule + this.from;

                if(!browser.ie) {
                    e.style.opacity = n;
                    e.style.KHTMLOpacity = n;
                } else {
                    e.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity:"+
                        Math.floor(n * 100) +")";
                }
            }
        }, options), "fx.opacity");

        return fx.launch();
    };


     
    /**
     * 渐现渐变效果。注意，如果元素的visibility属性如果为hidden，效果将表现不出来。
     * @function
     * @grammar fx.fadeIn(element, options)
     * @param      {string|HTMLElement}     element            元素或者元素的ID
     * @param      {Object}                 options            选项。参数的详细说明如下表所示
     * @config     {Number}                 duration           500,//效果持续时间，默认值为500ms
     * @config     {Number}                 interval           16, //动画帧间隔时间，默认值为16ms
     * @config     {Function}               transition         function(schedule){return schedule;},时间线函数
     * @config     {Function}               onbeforestart      function(){},//效果开始前执行的回调函数
     * @config     {Function}               onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config     {Function}               onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config     {Function}               onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config     {Function}               oncancel           function(){},//效果被撤销时的回调函数
     * @see fx.fadeOut
     */

    fx.fadeIn = function(element, options) {
        if (!(element = dom.g(element))) return null;

        var fx = fx.opacity(element,
            object.extend({from:0, to:1, restoreAfterFinish:true}, options||{})
        );
        fx.__type = "fx.fadeIn";

        return fx;
    };

     
    /**
     * 渐隐渐变效果，效果执行结束后会将元素完全隐藏起来。
     * @function
     * @grammar fx.fadeOut(element, options)
     * @param {string|HTMLElement} element 元素或者元素的ID
     * @param {Object} options 选项。参数的详细说明如下表所示
     * @config     {Number}                 duration           500,//效果持续时间，默认值为500ms
     * @config     {Number}                 interval           16, //动画帧间隔时间，默认值为16ms
     * @config     {Function}               transition         function(schedule){return schedule;},时间线函数
     * @config     {Function}               onbeforestart      function(){},//效果开始前执行的回调函数
     * @config     {Function}               onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config     {Function}               onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config     {Function}               onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config     {Function}               oncancel           function(){},//效果被撤销时的回调函数
     * @see fx.fadeIn
     * @remark
     * 1.0.0开始支持
     */
    fx.fadeOut = function(element, options) {
        if (!(element = dom.g(element))) return null;

        var fx = fx.opacity(element,
            object.extend({from:1, to:0, restoreAfterFinish:true}, options||{})
        );
        fx.addEventListener("onafterfinish", function(){dom.hide(this.element);});
        fx.__type = "fx.fadeOut";

        return fx;
    };

    /**
     * 获取线型函数
     * @function
     * @grammar fx.getTransition(name)
     * @param   {String}    name    transition的名称
     * @return  {function}          线型函数
     */
    fx.getTransition = function(name) {
        var a = fx.transitions;
        if (!name || typeof a[name] != "string") name = "linear";
        return new Function("percent", a[name]);
    };

    fx.transitions = {
        none : "return 0"
        ,full : "return 1"
        ,linear : "return percent"  // 斜线
        ,reverse : "return 1 - percent" // 反斜线
        ,parabola : "return Math.pow(percent, 2)"   // 抛物线
        ,antiparabola : "return 1 - Math.pow(1 - percent, 2)"   // 反抛物线
        ,sinoidal : "return (-Math.cos(percent * Math.PI)/2) + 0.5" // 正弦波
        ,wobble : "return (-Math.cos(percent * Math.PI * (9 * percent))/2) + 0.5"   // 摇晃
        ,spring : "return 1 - (Math.cos(percent * 4.5 * Math.PI) * Math.exp(-percent * 6))" // 弹性阴尼
    };

    /*
    //from: http://github.com/madrobby/scriptaculous/blob/master/src/effects.js

    Transitions: {
        linear: Prototype.K,
        sinoidal: function(pos) {
          return (-Math.cos(pos*Math.PI)/2) + .5;
        },
        reverse: function(pos) {
          return 1-pos;
        },
        flicker: function(pos) {
          var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
          return pos > 1 ? 1 : pos;
        },
        wobble: function(pos) {
          return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
        },
        pulse: function(pos, pulses) {
          return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
        },
        spring: function(pos) {
          return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
        },
        none: function(pos) {
          return 0;
        },
        full: function(pos) {
          return 1;
        }
    }

    Fx.Transitions.extend({

        Pow: function(p, x){
            return Math.pow(p, x[0] || 6);
        },

        Expo: function(p){
            return Math.pow(2, 8 * (p - 1));
        },

        Circ: function(p){
            return 1 - Math.sin(Math.acos(p));
        },

        Sine: function(p){
            return 1 - Math.sin((1 - p) * Math.PI / 2);
        },

        Back: function(p, x){
            x = x[0] || 1.618;
            return Math.pow(p, 2) * ((x + 1) * p - x);
        },

        Bounce: function(p){
            var value;
            for (var a = 0, b = 1; 1; a += b, b /= 2){
                if (p >= (7 - 4 * a) / 11){
                    value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
                    break;
                }
            }
            return value;
        },

        Elastic: function(p, x){
            return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
        }

    });

    ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
        Fx.Transitions[transition] = new Fx.Transition(function(p){
            return Math.pow(p, [i + 2]);
        });
    });


    //*/

    /**
     * 将各种浏览器里的颜色值转换成 #RRGGBB 的格式
     * @name string.formatColor
     * @function
     * @grammar string.formatColor(color)
     * @param {string} color 颜色值字符串
     * @version 1.3
     *             
     * @returns {string} #RRGGBB格式的字符串或空
     */
    (function(){
        // 将正则表达式预创建，可提高效率
        var reg1 = /^\#[\da-f]{6}$/i,
            reg2 = /^rgb\((\d+), (\d+), (\d+)\)$/,
            keyword = {
                black: '#000000',
                silver: '#c0c0c0',
                gray: '#808080',
                white: '#ffffff',
                maroon: '#800000',
                red: '#ff0000',
                purple: '#800080',
                fuchsia: '#ff00ff',
                green: '#008000',
                lime: '#00ff00',
                olive: '#808000',
                yellow: '#ffff0',
                navy: '#000080',
                blue: '#0000ff',
                teal: '#008080',
                aqua: '#00ffff'
            };

        string.formatColor = function(color) {
            if(reg1.test(color)) {
                // #RRGGBB 直接返回
                return color;
            } else if(reg2.test(color)) {
                // 非IE中的 rgb(0, 0, 0)
                for (var s, i=1, color="#"; i<4; i++) {
                    s = parseInt(RegExp["\x24"+ i]).toString(16);
                    color += ("00"+ s).substr(s.length);
                }
                return color;
            } else if(/^\#[\da-f]{3}$/.test(color)) {
                // 简写的颜色值: #F00
                var s1 = color.charAt(1),
                    s2 = color.charAt(2),
                    s3 = color.charAt(3);
                return "#"+ s1 + s1 + s2 + s2 + s3 + s3;
            }else if(keyword[color])
                return keyword[color];
            
            return "";
        };
    })();



     
    /**
     * 这个方法改变DOM元素的背景色，实现高亮的效果。
     * @function
     * @grammar fx.highlight(element, options)
     * @param      {string|HTMLElement}     element            元素或者元素的ID
     * @param      {Object}                 options            选项。参数的详细说明如下表所示
     * @config     {String}                 beginColor         渐变开始时的背景色，如果设置了背景色则以设置的颜色为默认开始颜色，否则默认为'#FFFF00'
     * @config     {String}                 endColor           渐变结束时的背景色，如果设置了背景色则以设置的颜色为默认结束颜色，否则默认为'#FFFFFF'
     * @config     {String}                 finalColor         渐变结束时的背景色，如果设置了背景色则以设置的颜色为结束时背景色，否则默认为endColor值
     * @config     {String}                 textColor          渐变结束时的背景色，如果设置了背景色则以设置的颜色为结束时文本的颜色，否则默认为原文本色值
     * @config     {Number}                 duration           500,//效果持续时间，默认值为500ms
     * @config     {Number}                 interval           16, //动画帧间隔时间，默认值为16ms
     * @config     {Function}               transition         function(schedule){return schedule;},时间线函数
     * @config     {Function}               onbeforestart      function(){},//效果开始前执行的回调函数
     * @config     {Function}               onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config     {Function}               onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config     {Function}               onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config     {Function}               oncancel           function(){},//效果被撤销时的回调函数
     */
    fx.highlight = function(element, options) {
        if (!(element = dom.g(element))) return null;

        var e = element;

        var fx = fx.create(e, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                var me = this,
                    CS = dom.getStyle,
                    FC = string.formatColor,
                    color = FC(CS(e, "color")) || "#000000",
                    bgc   = FC(CS(e, "backgroundColor"));

                // 给用户指定的四个配置参数做一个保护值
                me.beginColor = me.beginColor || bgc || "#FFFF00";
                me.endColor   = me.endColor   || bgc || "#FFFFFF";
                me.finalColor = me.finalColor || me.endColor || me.element.style.backgroundColor;
                me.textColor == color && (me.textColor = "");

                this.protect("color");
                this.protect("backgroundColor");

                me.c_b = []; me.c_d = []; me.t_b = []; me.t_d = [];
                for (var n, i=0; i<3; i++) {
                    n = 2 * i + 1;
                    me.c_b[i]=parseInt(me.beginColor.substr(n, 2), 16);
                    me.c_d[i]=parseInt(me.endColor.substr(n, 2), 16) - me.c_b[i];

                    // 如果指定了文字的颜色，则文字颜色也渐变
                    if (me.textColor) {
                        me.t_b[i]=parseInt(color.substr(n, 2), 16);
                        me.t_d[i]=parseInt(me.textColor.substr(n,2),16)-me.t_b[i];
                    }
                }
            }

            //[Implement Interface] render
            ,render : function(schedule) {
                for (var me=this, a="#", b="#", n, i=0; i<3; i++) {
                    n = Math.round(me.c_b[i] + me.c_d[i] * schedule).toString(16);
                    a += ("00"+ n).substr(n.length);

                    // 如果指定了文字的颜色，则文字颜色也渐变
                    if (me.textColor) {
                        n = Math.round(me.t_b[i]+me.t_d[i]*schedule).toString(16);
                        b += ("00"+ n).substr(n.length);
                    }
                }
                e.style.backgroundColor = a;
                me.textColor && (e.style.color = b);
            }

            //[Implement Interface] finish
            ,finish : function(){
                this.textColor && (e.style.color = this.textColor);
                e.style.backgroundColor = this.finalColor;
            }
        }, options || {}), "fx.highlight");

        return fx.launch();
    };

    /**
     * 面具遮罩效果。注意：只适用于绝对定位的DOM元素.
     * @function
     * @grammar fx.mask(element, options)
     * @param       {string|HTMLElement}      element           元素或者元素的ID
     * @param       {Object}                  options           选项。参数的详细说明如下表所示
     * @config      {String}                  startOrigin       "0px 0px",//起始坐标描述。"x y"：x方向和y方向坐标。取值包括像素(含px字符)，百分比，top、left、center、bottom、right，默认"0px 0px"。
     * @config      {Number}                  from              0,//效果起始值。介于0到1之间的一个数字，默认为0。
     * @config      {Number}                  to                1,//效果结束值。介于0到1之间的一个数字，默认为1。
     * @config      {Number}                  duration          500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval          16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition        function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart     function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate    function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate     function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish     function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel          function(){},//效果被撤销时的回调函数
     */
    fx.mask = function(element, options) {
        // mask 效果只适用于绝对定位的DOM元素
        if (!(element = dom.g(element)) ||
            dom.getStyle(element, "position") != "absolute")
            return null;

        var e = element, original = {};
        options = options || {};

        // [startOrigin] "0px 0px" "50% 50%" "top left"
        var r = /^(\d+px|\d?\d(\.\d+)?%|100%|left|center|right)(\s+(\d+px|\d?\d(\.\d+)?%|100%|top|center|bottom))?/i;
        !r.test(options.startOrigin) && (options.startOrigin = "0px 0px");

        var options = object.extend({restoreAfterFinish:true, from:0, to:1}, options || {});

        var fx = fx.create(e, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                e.style.display = "";
                this.protect("clip");
                original.width = e.offsetWidth;
                original.height = e.offsetHeight;

                // 计算效果起始点坐标
                r.test(this.startOrigin);
                var t1 = RegExp["\x241"].toLowerCase(),
                    t2 = RegExp["\x244"].toLowerCase(),
                    ew = this.element.offsetWidth,
                    eh = this.element.offsetHeight,
                    dx, dy;

                if (/\d+%/.test(t1)) dx = parseInt(t1, 10) / 100 * ew;
                else if (/\d+px/.test(t1)) dx = parseInt(t1);
                else if (t1 == "left") dx = 0;
                else if (t1 == "center") dx = ew / 2;
                else if (t1 == "right") dx = ew;

                if (!t2) dy = eh / 2;
                else {
                    if (/\d+%/.test(t2)) dy = parseInt(t2, 10) / 100 * eh;
                    else if (/\d+px/.test(t2)) dy = parseInt(t2);
                    else if (t2 == "top") dy = 0;
                    else if (t2 == "center") dy = eh / 2;
                    else if (t2 == "bottom") dy = eh;
                }
                original.x = dx;
                original.y = dy;
            }

            //[Implement Interface] render
            ,render : function(schedule) {
                var n = this.to * schedule + this.from * (1 - schedule),
                    top = original.y * (1 - n) +"px ",
                    left = original.x * (1 - n) +"px ",
                    right = original.x * (1 - n) + original.width * n +"px ",
                    bottom = original.y * (1 - n) + original.height * n +"px ";
                e.style.clip = "rect("+ top + right + bottom + left +")";
            }

            //[Implement Interface] finish
            ,finish : function(){
                if (this.to < this.from) e.style.display = "none";
            }
        }, options), "fx.mask");

        return fx.launch();
    };

     
    /**
     * 移动元素，将参数元素移动到指定位置。注意：对static定位的DOM元素无效。
     * @function
     * @grammar fx.move(element, options)
     * @param       {string|HTMLElement}      element           元素或者元素的ID
     * @param       {Object}                  options           选项。参数的详细说明如下表所示
     * @config      {Number}                  x                 0,//横坐标移动的偏移量，默认值为0px。
     * @config      {Number}                  y                 0,//纵坐标移动的偏移量，默认值为0px。
     * @config      {Number}                  duration          500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval          16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition        function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart     function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate    function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate     function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish     function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel          function(){},//效果被撤销时的回调函数
     * @remark
     * 1.0.0开始支持
     */
    fx.move = function(element, options) {
        if (!(element = dom.g(element))
            || dom.getStyle(element, "position") == "static") return null;
        
        options = object.extend({x:0, y:0}, options || {});
        if (options.x == 0 && options.y == 0) return null;

        var fx = fx.create(element, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                this.protect("top");
                this.protect("left");

                this.originX = parseInt(dom.getStyle(element, "left"))|| 0;
                this.originY = parseInt(dom.getStyle(element, "top")) || 0;
            }

            //[Implement Interface] transition
            ,transition : function(percent) {return 1 - Math.pow(1 - percent, 2);}

            //[Implement Interface] render
            ,render : function(schedule) {
                element.style.top  = (this.y * schedule + this.originY) +"px";
                element.style.left = (this.x * schedule + this.originX) +"px";
            }
        }, options), "fx.move");

        return fx.launch();
    };

     
    /**
     * 移动渐变效果。这个效果会使目标元素移动指定的距离。注意: 对static定位的DOM元素无效。
     * @function
     * @grammar fx.moveBy(element, distance, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Array|Object}            distance              偏移距离。若为数组，索引0为x方向，索引1为y方向；若为Object，键x为x方向，键y为y方向；单位：px，默认值为：0。
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                restore               restore方法,在onafterfinish与oncancel时默认调用
     * @config      {Boolean}                 restoreAfterFinish    默认为true，在onafterfinish与oncancel事件中调用restore方法。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     * @remark
     * 1.0.0开始支持
     * @see fx.moveBy
     */
    fx.moveBy = function(element, distance, options) {
        if (!(element = dom.g(element))
            || dom.getStyle(element, "position") == "static"
            || typeof distance != "object") return null;

        var d = {};
        d.x = distance[0] || distance.x || 0;
        d.y = distance[1] || distance.y || 0;

        var fx = fx.move(element, object.extend(d, options||{}));

        return fx;
    };

     
    /**
     * 移动渐变效果，该效果使元素移动到指定的位置。注意：对static定位的DOM元素无效。
     * @function
     * @grammar fx.moveTo(element, point, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Array|Object}            point                 目标点坐标。若为数组，索引0为x方向，索引1为y方向；若为Object，键x为x方向，键y为y方向；单位：px，默认值：元素本来的坐标。
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     * @remark
     * 1.0.0开始支持
     * @see fx.moveTo
     */
    fx.moveTo = function(element, point, options) {
        if (!(element = dom.g(element))
            || dom.getStyle(element, "position") == "static"
            || typeof point != "object") return null;

        var p = [point[0] || point.x || 0,point[1] || point.y || 0];
        var x = parseInt(dom.getStyle(element, "left")) || 0;
        var y = parseInt(dom.getStyle(element, "top"))  || 0;

        var fx = fx.move(element, object.extend({x: p[0]-x, y: p[1]-y}, options||{}));

        return fx;
    };


    /**
     * 将元素放大或缩小的效果。
     * @function
     * @grammar fx.scale(element, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {String}                  transformOrigin       "0px 0px",//起始坐标描述。"x y"：x方向和y方向坐标，取值包括像素(含px字符，百分比，top、left、center、bottom、right，默认"0px 0px"。
     * @config      {Number}                  from                  效果起始值，介于0到1之间的一个数字。
     * @config      {Number}                  to                    效果结束值，介于0到1之间的一个数字。
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Boolean}                 fade                  true，//渐变，默认为true
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     */
    fx.scale = function(element, options) {
        if (!(element = dom.g(element))) return null;
        options = object.extend({from : 0.1,to : 1}, options || {});

        // "0px 0px" "50% 50%" "top left"
        var r = /^(-?\d+px|\d?\d(\.\d+)?%|100%|left|center|right)(\s+(-?\d+px|\d?\d(\.\d+)?%|100%|top|center|bottom))?/i;
        !r.test(options.transformOrigin) && (options.transformOrigin = "0px 0px");

        var original = {},
            fx = fx.create(element, object.extend({
            fade: true,
                
            //[Implement Interface] initialize
            initialize : function() {
                dom.show(element);
                var me = this,
                    o = original,
                    s = element.style,
                    save    = function(k){me.protect(k)};

                // IE浏览器使用 zoom 样式放大
                if (browser.ie) {
                    save("top");
                    save("left");
                    save("position");
                    save("zoom");
                    save("filter");

                    this.offsetX = parseInt(dom.getStyle(element, "left")) || 0;
                    this.offsetY = parseInt(dom.getStyle(element, "top"))  || 0;

                    if (dom.getStyle(element, "position") == "static") {
                        s.position = "relative";
                    }

                    // IE 的ZOOM没有起始点，以下代码就是实现起始点
                    r.test(this.transformOrigin);
                    var t1 = RegExp["\x241"].toLowerCase(),
                        t2 = RegExp["\x244"].toLowerCase(),
                        ew = this.element.offsetWidth,
                        eh = this.element.offsetHeight,
                        dx, dy;

                    if (/\d+%/.test(t1)) dx = parseInt(t1, 10) / 100 * ew;
                    else if (/\d+px/.test(t1)) dx = parseInt(t1);
                    else if (t1 == "left") dx = 0;
                    else if (t1 == "center") dx = ew / 2;
                    else if (t1 == "right") dx = ew;

                    if (!t2) dy = eh / 2;
                    else {
                        if (/\d+%/.test(t2)) dy = parseInt(t2, 10) / 100 * eh;
                        else if (/\d+px/.test(t2)) dy = parseInt(t2);
                        else if (t2 == "top") dy = 0;
                        else if (t2 == "center") dy = eh / 2;
                        else if (t2 == "bottom") dy = eh;
                    }

                    // 设置初始的比例
                    s.zoom = this.from;
                    o.cx = dx; o.cy = dy;   // 放大效果起始原点坐标
                } else {
                    save("WebkitTransform");
                    save("WebkitTransformOrigin");   // Chrome Safari
                    save("MozTransform");
                    save("MozTransformOrigin");         // Firefox Mozllia
                    save("OTransform");
                    save("OTransformOrigin");             // Opera 10.5 +
                    save("transform");
                    save("transformOrigin");               // CSS3
                    save("opacity");
                    save("KHTMLOpacity");

                    // 设置初始的比例和效果起始点
                    s.WebkitTransform =
                        s.MozTransform =
                        s.OTransform =
                        s.transform = "scale("+ this.from +")";

                    s.WebkitTransformOrigin = 
                        s.MozTransformOrigin = 
                        s.OTransformOrigin =
                        s.transformOrigin = this.transformOrigin;
                }
            }

            //[Implement Interface] render
            ,render : function(schedule) {
                var s = element.style,
                    b = this.to == 1,
                    b = typeof this.opacityTrend == "boolean" ? this.opacityTrend : b,
                    p = b ? this.percent : 1 - this.percent,
                    n = this.to * schedule + this.from * (1 - schedule);

                if (browser.ie) {
                    s.zoom = n;
                    if(this.fade){
                        s.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity:"+
                            Math.floor(p * 100) +")";
                    }
                    
                    // IE 下得计算 transform-origin 变化
                    s.top = this.offsetY + original.cy * (1 - n);
                    s.left= this.offsetX + original.cx * (1 - n);
                } else {
                    s.WebkitTransform =
                        s.MozTransform =
                        s.OTransform =
                        s.transform = "scale("+ n +")";
                    if(this.fade){
                        s.KHTMLOpacity = s.opacity = p;
                    }
                }
            }
        }, options), "fx.scale");

        return fx.launch();
    };


     
    /**
     * 将元素缩小的消失效果。
     * @function
     * @grammar fx.zoomOut(element, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {String}                transformOrigin    "0px 0px",//起始坐标描述。"x y"：x方向和y方向坐标，取值包括像素(含px字符)，百分比，top、left、center、bottom、right，默认"0px 0px"。
     * @config    {Number}                from               1,//效果起始值。介于0到1之间的一个数字，默认为1。
     * @config    {Number}                to                 0.1,//效果结束值。介于0到1之间的一个数字，默认为0.1。
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms。
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms。
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     */
    fx.zoomOut = function(element, options) {
        if (!(element = dom.g(element))) return null;

        options = object.extend({
            to:0.1
            ,from:1
            ,opacityTrend:false
            ,restoreAfterFinish:true
            ,transition:function(n){return 1 - Math.pow(1 - n, 2);}
        },  options||{});

        var effect = fx.scale(element, options);
        effect.addEventListener("onafterfinish", function(){dom.hide(this.element);});

        return effect;
    };


    /**
     * 将DOM元素放大，关逐渐透明消失。
     * @function
     * @grammar fx.puff(element, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              800,//效果持续时间，默认值为800ms。
     * @config      {Number}                  to                    1.8,//放大倍数，默认1.8。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     * @remark
     * 1.0.0开始支持
     * @see fx.puff
     */
    fx.puff = function(element, options) {
        return fx.zoomOut(element,
            object.extend({
                to:1.8
                ,duration:800
                ,transformOrigin:"50% 50%"
            }, options||{})
        );
    };

     
    /**
     * 心跳闪现效果。
     * @function
     * @grammar fx.pulsate(element, loop, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Number}                  loop                  心跳次数，小于0则为永远跳动，默认为0次。
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     */
    fx.pulsate = function(element, loop, options) {
        if (!(element = dom.g(element))) return null;
        if (isNaN(loop) || loop == 0) return null;

        var e = element;

        var fx = fx.create(e, object.extend({
            //[Implement Interface] initialize
            initialize : function() {this.protect("visibility");}

            //[Implement Interface] transition
            ,transition : function(percent) {return Math.cos(2*Math.PI*percent);}

            //[Implement Interface] render
            ,render : function(schedule) {
                e.style.visibility = schedule > 0 ? "visible" : "hidden";
            }

            //[Implement Interface] finish
            ,finish : function(){
                setTimeout(function(){
                    fx.pulsate(element, --loop, options);
                }, 10);
            }
        }, options), "fx.pulsate");

        return fx.launch();
    };

     
    /**
     * 删除元素的时候使用fadeOut效果
     * @function
     * @grammar fx.remove(element, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     */

    fx.remove = function(element, options) {
        var afterFinish = options.onafterfinish ? options.onafterfinish : new Function();
        
        return fx.fadeOut(element, object.extend(options||{}, {
            onafterfinish: function(){
                dom.remove(this.element);
                afterFinish.call(this);
            }
        }));
    };


     
    /**
     * 按指定量移动滚动条。
     * @function
     * @grammar fx.scrollBy(element, distance, options)
     * @param       {string|HTMLElement}      element               元素或者元素的ID
     * @param       {Array|JSON}              distance              移动的距离 [,] | {x,y}，支持数组与JSON格式
     * @param       {Object}                  options               选项。参数的详细说明如下表所示
     * @config      {Number}                  duration              500,//效果持续时间，默认值为500ms。
     * @config      {Number}                  interval              16, //动画帧间隔时间，默认值为16ms。
     * @config      {Function}                transition            function(schedule){return schedule;},时间线函数
     * @config      {Function}                onbeforestart         function(){},//效果开始前执行的回调函数
     * @config      {Function}                onbeforeupdate        function(){},//每次刷新画面之前会调用的回调函数
     * @config      {Function}                onafterupdate         function(){},//每次刷新画面之后会调用的回调函数
     * @config      {Function}                onafterfinish         function(){},//效果结束后会执行的回调函数
     * @config      {Function}                oncancel              function(){},//效果被撤销时的回调函数
     */
    fx.scrollBy = function(element, distance, options) {
        if (!(element = dom.g(element)) || typeof distance != "object") return null;
        
        var d = {}, mm = {};
        d.x = distance[0] || distance.x || 0;
        d.y = distance[1] || distance.y || 0;

        var fx = fx.create(element, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                var t = mm.sTop   = element.scrollTop;
                var l = mm.sLeft  = element.scrollLeft;

                mm.sx = Math.min(element.scrollWidth - element.clientWidth - l, d.x);
                mm.sy = Math.min(element.scrollHeight- element.clientHeight- t, d.y);
            }

            //[Implement Interface] transition
            ,transition : function(percent) {return 1 - Math.pow(1 - percent, 2);}

            //[Implement Interface] render
            ,render : function(schedule) {
                element.scrollTop  = (mm.sy * schedule + mm.sTop);
                element.scrollLeft = (mm.sx * schedule + mm.sLeft);
            }

            ,restore : function(){
                element.scrollTop   = mm.sTop;
                element.scrollLeft  = mm.sLeft;
            }
        }, options), "fx.scroll");

        return fx.launch();
    };

     
    /**
     * 滚动条滚动到指定位置。
     * @function
     * @grammar fx.scrollTo(element, point, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Array|JSON}            point              移动的距离 [,] | {x,y}，支持数组与JSON格式
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms。
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms。
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     */
    fx.scrollTo = function(element, point, options) {
        if (!(element = dom.g(element)) || typeof point != "object") return null;
        
        var d = {};
        d.x = (point[0] || point.x || 0) - element.scrollLeft;
        d.y = (point[1] || point.y || 0) - element.scrollTop;

        return fx.scrollBy(element, d, options);
    };

     
    /**
     * 颤动的效果。
     * 说明：在效果执行过程中会修改DOM元素的position属性，可能会对包含的DOM元素带来影响
     * @function
     * @grammar fx.shake(element, offset, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Array|Object}          offset             震动范围。若为数组，索引0为x方向，索引1为y方向；若为Object，键x为x方向，键y为y方向；单位：px，默认值：元素本来的坐标。
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms。
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms。
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     */
    fx.shake = function(element, offset, options) {
        if (!(element = dom.g(element))) return null;

        var e = element;
        offset = offset || [];
        function tt() {
            for (var i=0; i<arguments.length; i++) {
                if (!isNaN(arguments[i])) return arguments[i];
            }
        }

        var fx = fx.create(e, object.extend({
            //[Implement Interface] initialize
            initialize : function() {
                this.protect("top");
                this.protect("left");
                this.protect("position");
                this.restoreAfterFinish = true;

                if (dom.getStyle(e, "position") == "static") {
                    e.style.position = "relative";
                }
                var original = this['\x06original'];
                this.originX = parseInt(original.left|| 0);
                this.originY = parseInt(original.top || 0);
                this.offsetX = tt(offset[0], offset.x, 16);
                this.offsetY = tt(offset[1], offset.y, 5);
            }

            //[Implement Interface] transition
            ,transition : function(percent) {
                var line = 1 - percent;
                return Math.floor(line * 16) % 2 == 1 ? line : percent - 1;
            }

            //[Implement Interface] render
            ,render : function(schedule) {
                e.style.top  = (this.offsetY * schedule + this.originY) +"px";
                e.style.left = (this.offsetX * schedule + this.originX) +"px";
            }
        }, options || {}), "fx.shake");

        return fx.launch();
    };

     
    /**
     * 将元素放大的展现效果。
     * @function
     * @grammar fx.zoomIn(element, options)
     * @param     {string|HTMLElement}    element            元素或者元素的ID
     * @param     {Object}                options            选项。参数的详细说明如下表所示
     * @config    {String}                transformOrigin    "0px 0px",//起始坐标描述。"x y"：x方向和y方向坐标，取值包括像素(含px字符)，百分比，top、left、center、bottom、right，默认"0px 0px"。
     * @config    {Number}                from               0.1,//效果默认起始值
     * @config    {Number}                to                 1,//效果结束默认值，输入的数值越大，图片显示的越大。
     * @config    {Number}                duration           500,//效果持续时间，默认值为500ms。
     * @config    {Number}                interval           16, //动画帧间隔时间，默认值为16ms。
     * @config    {Function}              transition         function(schedule){return schedule;},时间线函数
     * @config    {Function}              onbeforestart      function(){},//效果开始前执行的回调函数
     * @config    {Function}              onbeforeupdate     function(){},//每次刷新画面之前会调用的回调函数
     * @config    {Function}              onafterupdate      function(){},//每次刷新画面之后会调用的回调函数
     * @config    {Function}              onafterfinish      function(){},//效果结束后会执行的回调函数
     * @config    {Function}              oncancel           function(){},//效果被撤销时的回调函数
     */
    fx.zoomIn = function(element, options) {
        if (!(element = dom.g(element))) return null;

        options = object.extend({
            to:1
            ,from:0.1
            ,restoreAfterFinish:true
            ,transition:function(n){return Math.pow(n, 2)}
        },  options||{});

        return fx.scale(element, options);
    };

})(window, T, T.util, T.object, T.string, T.dom);